package devices;


public class PadWindow extends javax.swing.JFrame implements core.interfaces.DeviceInterface{
	private static final long serialVersionUID = 1L;

	private core.MemoryClass mem = null;
	private core.interfaces.MemoryCallbackInterface cal = null;
	protected gui.callback.PadCallbackInterface mainWindow = null;
	private javax.swing.JTextField buttonsDisplay = null;
	private short buttonsValue = 0;
	private javax.swing.JTextField[] memDisplay = new javax.swing.JTextField[6];
	private javax.swing.JPanel displayPanel = null;
	private javax.swing.JPanel buttonsPanel = null;

	private core.interfaces.InterruptInterface interrupt = null;

	private int buttonsAddress = 0xFFF0;
	private int memAddress = 0xFFF1;
	private int interruptLine = 3;

	public PadWindow(){
		super();
		this.init(null, null, null, null, this.buttonsAddress, this.interruptLine);
	}
	public PadWindow(core.MemoryClass mem, core.interfaces.MemoryCallbackInterface cal){
		super();
		this.init(mem, cal, null, null, this.buttonsAddress, this.interruptLine);
	}
	public PadWindow(core.MemoryClass mem, core.interfaces.MemoryCallbackInterface cal, core.interfaces.InterruptInterface interrupt){
		super();
		this.init(mem, cal, null, interrupt, this.buttonsAddress, this.interruptLine);
	}
	public PadWindow(core.MemoryClass mem, core.interfaces.MemoryCallbackInterface cal, gui.callback.PadCallbackInterface mainWindow){
		super();
		this.init(mem, cal, mainWindow, null, this.buttonsAddress, this.interruptLine);
	}
	public PadWindow(core.MemoryClass mem, core.interfaces.MemoryCallbackInterface cal, gui.callback.PadCallbackInterface mainWindow, core.interfaces.InterruptInterface interrupt){
		super();
		this.init(mem, cal, mainWindow, interrupt, this.buttonsAddress, this.interruptLine);
	}
	public PadWindow(core.MemoryClass mem, core.interfaces.MemoryCallbackInterface cal, gui.callback.PadCallbackInterface mainWindow, core.interfaces.InterruptInterface interrupt, int baseAddr, int interruptLine){
		super();
		this.init(mem, cal, mainWindow, interrupt, baseAddr, interruptLine);
	}

	private void informClose(){
		if(this.mainWindow != null){
			this.mainWindow.padClosed();
		}
	}

	private void informaCanviTamany(){
		if(this.mainWindow != null){
			this.mainWindow.padMoved();
		}
	}
	private void init(core.MemoryClass mem, core.interfaces.MemoryCallbackInterface cal, gui.callback.PadCallbackInterface mainWindow, core.interfaces.InterruptInterface interrupt, int baseAddr, int interruptLine){
		this.mem = mem;
		this.cal = cal;
		this.mainWindow = mainWindow;
		this.interrupt = interrupt;
		this.setBaseAddress(baseAddr);
		this.setInterruptLine(interruptLine);
		this.setSize(new java.awt.Dimension(224,350));
		this.addWindowListener(new java.awt.event.WindowAdapter() {
			public void windowClosing(java.awt.event.WindowEvent e) {
				informClose();
			}
		});
		this.addComponentListener(new java.awt.event.ComponentAdapter(){
			public void componentResized(java.awt.event.ComponentEvent e) {
				informaCanviTamany();
			}
			public void componentMoved(java.awt.event.ComponentEvent e) {
				informaCanviTamany();
			}
		});
		this.setTitle("SEP16 Pad");
		this.pack();
		this.getContentPane().setLayout(new java.awt.GridBagLayout());
		java.awt.GridBagConstraints c;
		c = new java.awt.GridBagConstraints(0, 2, 1, 1, 1.0, 1.0, java.awt.GridBagConstraints.CENTER, java.awt.GridBagConstraints.BOTH, new java.awt.Insets(5,10,10,10), 0, 0);
		this.getContentPane().add(this.getButtonsPanel(),c);
		c = new java.awt.GridBagConstraints(0, 1, 1, 1, 1.0, 0.0, java.awt.GridBagConstraints.CENTER, java.awt.GridBagConstraints.BOTH, new java.awt.Insets(10,10,0,10), 0, 0);
		this.getContentPane().add(this.getButtonsDisplay(),c);
		c = new java.awt.GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, java.awt.GridBagConstraints.CENTER, java.awt.GridBagConstraints.BOTH, new java.awt.Insets(10,10,0,10), 0, 0);
		this.getContentPane().add(this.getMemDisplay(),c);
		this.pack();
		this.setVisible(true);
	}

	public void reloadMemDisplayValue(){
		for(int i=0; i<6; i++){
			if(this.mem != null){
				this.memDisplay[i].setText(java.lang.String.format("%c", (0x0000FFFF & this.mem.getWord(this.memAddress + i))));
			}else{
				this.memDisplay[i].setText("0");
			}
		}
	}
	private javax.swing.JPanel getMemDisplay(){
		this.displayPanel = new javax.swing.JPanel(new java.awt.BorderLayout());
		this.displayPanel.setBorder(new javax.swing.border.TitledBorder(java.lang.String.format("Mem Value for 0x%04X", this.memAddress)));
		javax.swing.JPanel auxp = new javax.swing.JPanel(new java.awt.GridLayout(1,6));

		for(int i=0; i<6; i++){
			this.memDisplay[i] = new javax.swing.JTextField(1);
			this.memDisplay[i].setFont(new java.awt.Font(java.awt.Font.MONOSPACED, java.awt.Font.BOLD, 30));
			this.memDisplay[i].setBackground(java.awt.Color.black);
			this.memDisplay[i].setForeground(java.awt.Color.lightGray);
			this.memDisplay[i].setHorizontalAlignment(javax.swing.JTextField.CENTER);
			this.memDisplay[i].setEditable(false);
			auxp.add(this.memDisplay[i]);
		}
		this.reloadMemDisplayValue();
		this.displayPanel.add(auxp);
		return(this.displayPanel);
	}
	private javax.swing.JPanel getButtonsDisplay(){
		this.buttonsPanel = new javax.swing.JPanel(new java.awt.BorderLayout());
		this.buttonsPanel.setBorder(new javax.swing.border.TitledBorder(java.lang.String.format("Set Value for 0x%04X", this.buttonsAddress)));
		this.buttonsDisplay = new javax.swing.JTextField(java.lang.String.format("0x%04X", this.buttonsValue));
		this.buttonsDisplay.setFont(new java.awt.Font(java.awt.Font.MONOSPACED, java.awt.Font.BOLD, 30));
		this.buttonsDisplay.setBackground(java.awt.Color.black);
		this.buttonsDisplay.setForeground(java.awt.Color.lightGray);
		this.buttonsDisplay.setHorizontalAlignment(javax.swing.JTextField.CENTER);
		this.buttonsDisplay.setEditable(false);
		this.buttonsPanel.add(this.buttonsDisplay);
		return(this.buttonsPanel);
	}
	private void buttonPressed(int val){
		switch(val){
			case 0:
			case 1:
			case 2:
			case 3:
			case 4:
			case 5:
			case 6:
			case 7:
			case 8:
			case 9:
			case 10:
			case 11:
			case 12:
			case 13:
			case 14:
			case 15:
				this.buttonsValue = (short)((((this.buttonsValue<<4) & 0x0000FFFF))|(val & 0x0000000F));
				this.buttonsDisplay.setText(java.lang.String.format("0x%04X", this.buttonsValue));
				break;
			case 16://Enter
				if(this.mem != null){
					mem.setWord(this.buttonsAddress, this.buttonsValue);
					cal.memoryChanged();
				}else{
					System.out.printf("0x%04x\n", this.buttonsValue);
				}
				if(this.interrupt != null){
					this.interrupt.raiseInterruptLine(this.interruptLine);
				}
				break;
			case 17://Reset
				if(this.mem != null){
					this.buttonsValue = mem.getWord(this.buttonsAddress);
					this.buttonsDisplay.setText(java.lang.String.format("0x%04X", this.buttonsValue));
				}
				break;
		}
	}
	private javax.swing.JButton getButton(int value){
		int aux_value = (value & 0x0000000F);
		javax.swing.JButton button = new javax.swing.JButton(java.lang.String.format("%01X", aux_value));
		button.setFont(new java.awt.Font(java.awt.Font.MONOSPACED, java.awt.Font.BOLD, 17));
		button.addActionListener(new ButtonListener(value));
		return(button);
	}
	private javax.swing.JButton getButton(int value, java.lang.String text){
		javax.swing.JButton button = new javax.swing.JButton(java.lang.String.format(text));
		button.setFont(new java.awt.Font(java.awt.Font.MONOSPACED, java.awt.Font.BOLD, 17));
		button.addActionListener(new ButtonListener(value));
		return(button);
	}
	private javax.swing.JPanel getButtonsPanel(){
		javax.swing.JPanel buttonPanel = new javax.swing.JPanel(new java.awt.GridBagLayout());
		java.awt.GridBagConstraints c;
		c = new java.awt.GridBagConstraints();
		buttonPanel.add(getButton(0), c);
		buttonPanel.add(getButton(1), c);
		buttonPanel.add(getButton(2), c);
		buttonPanel.add(getButton(3), c);
		c.gridy = 1;
		buttonPanel.add(getButton(4), c);
		buttonPanel.add(getButton(5), c);
		buttonPanel.add(getButton(6), c);
		buttonPanel.add(getButton(7), c);
		c.gridy = 2;
		buttonPanel.add(getButton(8), c);
		buttonPanel.add(getButton(9), c);
		buttonPanel.add(getButton(10), c);
		buttonPanel.add(getButton(11), c);
		c.gridy = 3;
		buttonPanel.add(getButton(12), c);
		buttonPanel.add(getButton(13), c);
		buttonPanel.add(getButton(14), c);
		buttonPanel.add(getButton(15), c);
		c.gridy = 4; c.gridwidth = 2; c.fill = java.awt.GridBagConstraints.BOTH;
		buttonPanel.add(getButton(16, "Enter"), c);
		buttonPanel.add(getButton(17, "Reset"), c);
		return(buttonPanel);
	}

	private class ButtonListener implements java.awt.event.ActionListener{
		int value = 0;
		public ButtonListener(int value){
			this.value = value;
		}
		public void actionPerformed(java.awt.event.ActionEvent e){
			buttonPressed(value);
		}
	}
	/**
	 * DeviceInterface Methods:
	 */
	public int getBaseAddress() {
		return(this.buttonsAddress);
	}
	public int getInterruptLine() {
		return(this.interruptLine);
	}
	public int getMemSize() {
		return(7);
	}
	public void setBaseAddress(int baseAddr) {
		this.buttonsAddress = baseAddr;
		this.memAddress = baseAddr + 1;
	}
	public void setInterruptLine(int line) {
		this.interruptLine = line;
	}
}
